unit smPlayer;

interface

uses
  SysUtils, Classes, smWorld, smCommonTypes, smExceptions;

type
  TPlayer = class(TObject)
  protected
    FName: AnsiString;
    FFileName: String;
    FWorld: TWorld;
    FReady: Boolean;

    function ReadFromFile(const AFileStream: TStream): Boolean;

  public
    property Name: AnsiString read FName write FName;
    property FileName: String read FFileName;
    property World: TWorld read FWorld;
    property Ready: Boolean read FReady;

    procedure New();
    procedure Load(const AFileName: String);
    procedure Save(const AFileName: String = '');
    procedure Clear();

    constructor Create();
    destructor Destroy(); override;
  end;

var
  Player: TPlayer;

implementation

uses
  smLuaUtils;

{ TPlayer }

constructor TPlayer.Create;
begin
  inherited Create();
  FWorld := TWorld.Create();
  Clear();
end;

function TPlayer.ReadFromFile(const AFileStream: TStream): Boolean;
var
  InitPos: Cardinal;
begin
  InitPos := AFileStream.Position;

  try
    FName := AFileStream.ReadString(); // Player's name

    Result := AFileStream.ReadDWord() = $FF00FF00;
  except
    Result := False;
    if Assigned(AFileStream) then
      AFileStream.Position := InitPos;
  end;
end;

destructor TPlayer.Destroy;
begin
  Clear();
  FWorld.Free();
  inherited;
end;

procedure TPlayer.New;
begin
  Load('start.wld');
end;

procedure TPlayer.Load(const AFileName: String);
var
  FStream: TFileStream;
begin
  if FReady then
    Clear();

  FStream := nil;

  try
    FFileName := Format('data\%s', [AFileName]);
    if not FileExists(FFileName, False) then
      raise EPlayerFileNotFound.CreateFmt(
        'no such file or folder "%s"', [FFileName]
      );

    FStream := TFileStream.Create(FFileName, fmOpenRead or fmShareDenyWrite);
    if not Self.ReadFromFile(FStream) then
      raise EPlayerFileReadError.CreateFmt(
        'cannot read player info from file "%s"', [AFileName]
      );

    World.Clear();
    if not FWorld.ReadFromFile(FStream) then
      raise EPlayerFileReadError.CreateFmt(
        'cannot read world information from file "%s"', [AFileName]
      );

    FReady := World.State = wsPreloaded;

  except
    Clear();
  end;

  if Assigned(FStream) then
    FStream.Free();
end;

procedure TPlayer.Save(const AFileName: String);
begin
  if FReady then
  begin

  end;
end;

procedure TPlayer.Clear;
begin
  FReady := False;
  FName  := EmptyAnsiStr;
  FFileName := EmptyStr;

  World.Clear();
end;

end.
